
const {ccclass, property} = cc._decorator;

@ccclass('changeSkin')
export default class changeSkin extends cc.Component {

    @property(sp.Skeleton)
    skin1Skel: sp.Skeleton = null;

    private skinIdx: number = 0;

    start () {
        if (CC_JSB) {
            // @ts-ignore
            let skeleton = sp.Skeleton.prototype;

            // 局部换装
            // @ts-ignore
            skeleton.updateRegion = function (attachment: any, tex2d: any) {                
                // @ts-ignore
                var jsbTex2d = new middleware.Texture2D();
                jsbTex2d.setNativeTexture(tex2d.getImpl());
                jsbTex2d.setPixelsWide(tex2d.width);
                jsbTex2d.setPixelsHigh(tex2d.height);
                // @ts-ignore
                sp.spine.updateRegion(attachment, jsbTex2d);
            }
        } else {
            // @ts-ignore
            let skeleton = sp.Skeleton.prototype;

            // 局部换装
            // @ts-ignore
            skeleton.updateRegion = function (attachment: any, tex2d: any) {
                // @ts-ignore
                const skeTexture = new sp.SkeletonTexture({ width: tex2d.width, height: tex2d.height } as ImageBitmap);
                skeTexture.setRealTexture(tex2d);

                const region = new sp.spine.TextureAtlasRegion();
                region.width = tex2d.width;
                region.height = tex2d.height;
                region.originalWidth = tex2d.width;
                region.originalHeight = tex2d.height;
                region.rotate = false;
                region.u = 0;
                region.v = 0;
                region.u2 = 1;
                region.v2 = 1;
                region.texture = skeTexture;
                region.renderObject = region;

                attachment.region = region;
                attachment.width = tex2d.width;
                attachment.height = tex2d.height;

                if (attachment instanceof sp.spine.MeshAttachment) {
                    attachment.updateUVs();
                } else {
                    attachment.setRegion(region);
                    attachment.updateOffset();
                }
            }
        }
    }

    protected async onChangeSkin() {
        if (this.skinIdx === 0) {
            this.skinIdx = 1;

            // 更换texture2d
            this.modifyAttachment('hair_b_9');
        } else {
            this.skinIdx = 0;

            // 更换texture2d
            this.modifyAttachment('hair_f_4');
        }
    }

    private async modifyAttachment(imgName: string) {
        let attachment = null;
        let slot = null;

        // skin1换装
        slot = this.skin1Skel!.findSlot('gun');
        attachment = slot.getAttachment();

        if (attachment === null) {
            console.log('getAttachment is null');
            return;
        }

        const tex2d = await this.loadTex2d(imgName) as cc.Texture2D;
        if (tex2d === null) {
            return;
        }

        // @ts-ignore
        this.skin1Skel.updateRegion(attachment, tex2d);
    }

    private loadTex2d(name: string) {
        return new Promise((resolve: Function, reject: Function) => {
            cc.resources!.load(`role/${name}`, cc.Texture2D, (err: Error | null, tex2d: cc.Texture2D) => {
                if (err !== null && err !== undefined) {
                    console.error(`loadTex2d ${name} error:`, err);
                    return reject(err);
                }

                resolve(tex2d);
            });
        });
    }
}
